<template>
  <div class="props-table">
    <div v-for="(value, key) in finalProps" :key="key" class="prop-item">
      <div class="props-wrapper">
        <span class="props-name">{{ value.name }}</span>
        <component
          v-if="value"
          :is="value.component"
          :[value.valueProp]="value.value"
          class="props-component"
          v-on="value.events"
        >
          <template v-if="value.options">
            <component
              :is="value.subComponent"
              v-for="(options, index) in value.options"
              :key="index"
              :[value.valueProp]="options.value"
            >
              <render-vnode :vNode="options.name"></render-vnode>
            </component>
          </template>
        </component>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, computed, PropType, VNode } from "vue";
import { reduce } from "lodash";
import { TextComponentProps } from "../defaultProps";
import { mapPropsToForms, PropsToForms } from "../propsMap";
import RenderVnode from "./RenderVnode";
import ColorPicker from './ColorPicker.vue'
export interface FormProps {
  component: string;
  value: string;
  name?: string;
  extraProps?: { [key: string]: any };
  options?: { name: string | VNode; value: any }[];
  subComponent?: string;
  initalTransform?: (v: any) => any;
  valueProp: string;
  eventName: string;
  events: { [key: string]: (e: any) => void };
  afterTransform?: (v: any) => any;
}
export default defineComponent({
  name: "props-table",
  props: {
    attrProps: {
      type: Object as PropType<TextComponentProps>,
    },
  },
  emits: ["change"],
  components: {
    RenderVnode,
    ColorPicker
  },
  setup(props, context) {
    /**
     * reduce方法将
     * {text:'',fontSize:''}根据类型定义转换成下面形式
     * finalProps={
     * text:{
     *  component:'',
     *  name:'',
     * },
     *  fontSize:{
     *  component:'',
     *  name:'',
     * }
     * }
     */
    const finalProps = computed(() => {
      return reduce(
        props.attrProps,
        (result, value, key) => {
          const newKey = key as keyof TextComponentProps; //keyof 可以将interface里的字面量全部提取出来 使得变量拥有更多可能的类型
          const item = mapPropsToForms[newKey];
          if (item) {
            const {
              valueProp = "value",
              eventName = "change",
              initalTransform,
              afterTransform,
            } = item;
            const newItem: FormProps = {
              ...item,
              value: initalTransform ? initalTransform(value) : value,
              valueProp,
              eventName,
              events: {
                [eventName]: (e: any) => {
                  context.emit("change", {
                    key,
                    value: afterTransform ? afterTransform(e) : e,
                  });
                },
              },
            };
            result[newKey] = newItem;
          }
          return result;
        },
        {} as { [key: string]: FormProps } //Required必选 required<PropsToForm> { [key: string]: FormProps}代表key值遵循string,且key的值范围不能超过FormProps
      );
    });
    return {
      finalProps,
    };
  },
});
</script>
<style>
.props-wrapper {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-bottom: 20px;
}
.props-name {
  width: 50px;
}
.props-component {
  /* flex: 1; */
}
</style>
